#ifndef __PACKET_CAPTURE_H__
#define __PACKET_CAPTURE_H__

#include "public.h"

#ifdef __cplusplus
extern "C" {
#endif

    union thdr
    {
        struct tpacket2_hdr *h2;
        u_int8_t            *raw;
    };

    typedef struct _afpacket_entry
    {
        struct _afpacket_entry *next;
        union thdr              hdr;
    }afpacket_entry;

    typedef struct _afpacket_ring
    {
        struct tpacket_req  layout;
        u_int32_t           size;
        void                *start;
        afpacket_entry      *entry;  
        afpacket_entry      *cursor;
    }afpacket_ring;

    typedef struct _afpacket_statistics
    {
        u_int64_t   hw_packets_received;    // packets received by hardware
        u_int64_t   hw_packets_dropped;     // packets dropped by hardware
        u_int64_t   packets_received;       // packets received by instance
        u_int64_t   packets_filtered;       // packets filtered by instance`s BPF
    }afpacket_statistics;

    typedef struct _afpacket_instance
    {
        char                *name;
        int                 fd;
        u_int32_t           ring_size;
        u_int32_t           snaplen;
        u_int32_t           index;
        struct sockaddr_ll  sll;
        u_int16_t           tp_version;
        u_int16_t           tp_hdrlen;
        afpacket_ring       rx_ring;
        afpacket_ring       tx_ring;
        void                *buffer;
        afpacket_statistics stats;
    }afpacket_instance;

    /* ====================================================== */
    extern int afpacket_init(const char *dev_name, void **context_ptr);
    extern int afpacket_start(void *ins, u_int8_t flag);     // send:0, recv:1
    extern int afpacket_send(void *ins, yx_pkt *pkt);
    extern int afpacket_close(void *ins);
    extern int afpacket_poll(void *ins, yx_pkt *pkt, u_int32_t len);

#ifdef __cpluscplus
}
#endif

#endif
